/***************************************************************************
 *   Copyright (C) 2009 by Zheng Yonglei
 *   zhengyonglei@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include "WordBrowser.h"
#include "Logger.h"

WordBrowser::WordBrowser(QWidget* parent) :
	QTextBrowser(parent)
{
	this->setReadOnly(true);
	this->setOpenLinks(false);
}

WordBrowser::~WordBrowser()
{
}

void WordBrowser::setWordInfo(WordManager* wm, bool clear)
{
	Word* word = wm->getCurWord();
	if (word)
	{
		if (clear)
			this->clear();
		mWord = word->word;
		//LOG<<"mWord="<<mWord<<endl;

		//insert basic information
		QString wordHtml = QString("<h1 align=\"left\"><a href=\"key:%1\">%1</h1><br>").arg(mWord);
		this->insertHtml(wordHtml);
		QString phoneticSymbol = translateSoundMark(word->phoneticSymbol);
		this->insertHtml(phoneticSymbol);
		QString exp = word->simpleExplanation + "<br>";
		this->insertHtml(exp);

		//insert extra information
		insertThesaurusLinks(wm);
		insertSimilarWordLinks(wm);
	}
}

void WordBrowser::insertSimilarWordLinks(WordManager* wm)
{
	set<QString>& wordSet = wm->getWordSet();
	int displayMax = 5;
	int distanceMax = 3;
	int limit = 100;
	QStringList finalWordList;
	map<int, QStringList> candidateMap;
	for (	set<QString>::iterator set_it = wordSet.begin();
			set_it != wordSet.end();
			set_it++)
	{
		QString target = *set_it;
		if (target == mWord)
			continue;

		int result = mEditDistance.CalEditDistance(mWord.toUtf8().data(), target.toUtf8().data(), limit);
		if (result <= distanceMax)
			candidateMap[result].push_back(target);
	}

	for (	map<int, QStringList >::iterator can_it = candidateMap.begin();
			can_it != candidateMap.end();
			can_it++)
	{
		for (int i=0; i<can_it->second.size(); i++)
		{
			finalWordList.push_back(can_it->second[i]);
		}
	}

	//LOG<<"finalWordList.size()="<<finalWordList.size()<<endl;
	if (finalWordList.size() > 0)
	{
		this->insertHtml(QString("<font color='#009933'>[Similar Words]</font><br>"));
		for (int i=0; i<finalWordList.size() && i < displayMax; i++)
		{
			this->insertHtml(QString("<a href=\"key:%1\">%1</a>  ").arg(finalWordList[i]));
		}

		this->insertHtml("<br><br>");
	}
}

void WordBrowser::insertThesaurusLinks(WordManager* wm)
{
	QStringList thesaurusList = DM.lookupThesaurus(mWord);
	if (thesaurusList.isEmpty())
		return;

	set<QString>& wordSet = wm->getWordSet();
	QString html;
	QString title = QString("<font color='#009933'>[Thesaurus]</font><br>");
	for (int i=0; i<thesaurusList.size(); i++)
	{
		QStringList subList = thesaurusList[i].split("|");
		for (int j=0; j<subList.size(); j++)
		{
			QString type = subList[j].left(subList[j].indexOf(":"));
			if (type.contains("Function"))
				continue;

			QString typeHtml = QString("%1: ").arg(type);
			QString wordHtml;
			QStringList wordList = subList[j].right(subList[j].size() - subList[j].indexOf(":") - 1).split(",");
			for (int k=0; k<wordList.size(); k++)
			{
				QString word = wordList[k];
				for (int p=0; p<word.size(); p++)
				{
					if (word[p].isUpper())
					{
						word[p] = word[p].toLower();
					}
				}

				set<QString>::iterator it = wordSet.find(word);
				if (it != wordSet.end())
				{
					wordHtml.append(QString("<a href=\"key:%1\">%2</a>  ").arg(word, wordList[k]));
				}
			}

			if (!wordHtml.isEmpty())
				html.append(typeHtml + wordHtml + "<br>");
		}
	}

	if (!html.isEmpty())
	{
		this->insertHtml(title);
		this->insertHtml(html);
		this->insertHtml("<br>");
	}
}

void WordBrowser::insertTransformationLinks(WordManager* wm)
{
	map<QString, QString>& transMap = wm->getWordTransformation();
	map<QString, QString>::iterator it = transMap.find(mWord);
	if (it == transMap.end())
		return;
	else
	{
		QString title = QString("<font color='#009933'>[Transformation]</font><br>");
		QString content;
		QString word = it->first;
		QStringList transList = it->second.split("|");
		for (int i=0; i<transList.size(); i++)
		{
			QString type = transList[i].left(transList[i].indexOf(":"));
			QString word = transList[i].right(transList[i].size() - transList[i].indexOf(":") - 1);
			content.append(type);
			content.append(QString(": <a href=\"key:%1\">%1</a><br>").arg(word));
		}

		if (content.isEmpty())
			return;
		else
		{
			this->insertHtml(title);
			this->insertHtml(content);
			this->insertHtml("<br>");
		}
	}
}

QString WordBrowser::translateSoundMark(QString phoneticSymbol)
{
	if (!phoneticSymbol.isEmpty())
	{
		map<QChar, vector<int> > markPos;
		for (int i=phoneticSymbol.size()-1; i>=0; i--)
		{
			if (phoneticSymbol[i] == '0') phoneticSymbol.replace(i, 1, "&#240;");
			if (phoneticSymbol[i] == '1') phoneticSymbol.replace(i, 1, "&#230;");
			if (phoneticSymbol[i] == '2') phoneticSymbol.replace(i, 1, "&#594;");
			if (phoneticSymbol[i] == '3') phoneticSymbol.replace(i, 1, "&#596;");
			if (phoneticSymbol[i] == '4') phoneticSymbol.replace(i, 1, "&#601;");
			if (phoneticSymbol[i] == '5') phoneticSymbol.replace(i, 1, "&#643;");
			if (phoneticSymbol[i] == '6') phoneticSymbol.replace(i, 1, "&#331;");
			if (phoneticSymbol[i] == '7') phoneticSymbol.replace(i, 1, "&#952;");
			if (phoneticSymbol[i] == '8') phoneticSymbol.replace(i, 1, "&#652;");
			if (phoneticSymbol[i] == '9') phoneticSymbol.replace(i, 1, "&#658;");
			if (phoneticSymbol[i] == 'A') phoneticSymbol.replace(i, 1, "&#1108;");
			if (phoneticSymbol[i] == '\\') phoneticSymbol.replace(i, 1, "&#604;");
			if (phoneticSymbol[i] == 'W') phoneticSymbol.replace(i, 1, "\'");
			if (phoneticSymbol[i] == '`') phoneticSymbol.replace(i, 1, ",");
		}

		phoneticSymbol.prepend("[");
		phoneticSymbol.append("]<br>");
	}

	return phoneticSymbol;
}

